#include <X11/Xlib.h>
#include <X11/Xatom.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

// 从 XSettings 获取缩放值
double get_scale_from_xsettings(Display *dpy) {
    Atom xsettings_atom = XInternAtom(dpy, "_XSETTINGS_SETTINGS", False);
    if (xsettings_atom == None) return 0;
    
    Atom actual_type;
    int actual_format;
    unsigned long nitems, bytes_after;
    unsigned char *data = NULL;
    
    // 获取 XSettings 属性
    if (XGetWindowProperty(dpy, DefaultRootWindow(dpy), xsettings_atom, 0, 1024,
                           False, AnyPropertyType, &actual_type, &actual_format,
                           &nitems, &bytes_after, &data) == Success) {
        if (data && actual_type != None && actual_format == 8) {
            // 解析 XSettings 数据 (简化版)
            unsigned char *p = data;
            while (p < data + nitems) {
                // 跳过类型和序列号
                p += 2 * sizeof(unsigned short);
                
                // 获取名称长度
                unsigned short name_len = *(unsigned short *)p;
                p += sizeof(unsigned short);
                
                // 检查名称是否为缩放设置
                char *name = (char *)p;
                p += name_len;
                
                // 对齐到4字节边界
                while ((unsigned long)p % 4 != 0) p++;
                
                // 获取值类型
                Atom value_type = *(Atom *)p;
                p += sizeof(Atom);
                
                // 获取值长度
                unsigned int value_len = *(unsigned int *)p;
                p += sizeof(unsigned int);
                
                // 检查是否为缩放设置
                if (strcmp(name, "Gdk/WindowScalingFactor") == 0 && 
                    value_type == XA_INTEGER && value_len >= sizeof(int)) {
                    int scale_value = *(int *)p;
                    XFree(data);
                    return (double)scale_value;
                }
                
                p += value_len;
                // 对齐到4字节边界
                while ((unsigned long)p % 4 != 0) p++;
            }
        }
        XFree(data);
    }
    return 0;
}

// 从 GTK 设置获取缩放值
double get_scale_from_gtk_settings(Display *dpy) {
    Atom gtk_scale_atom = XInternAtom(dpy, "_GTK_DPI", False);
    if (gtk_scale_atom == None) return 0;
    
    Atom actual_type;
    int actual_format;
    unsigned long nitems, bytes_after;
    unsigned char *data = NULL;
    
    // 获取 GTK DPI 属性
    if (XGetWindowProperty(dpy, DefaultRootWindow(dpy), gtk_scale_atom, 0, 1,
                           False, XA_CARDINAL, &actual_type, &actual_format,
                           &nitems, &bytes_after, &data) == Success) {
        if (data && actual_type == XA_CARDINAL && actual_format == 32 && nitems == 1) {
            unsigned long dpi = *(unsigned long *)data;
            XFree(data);
            
            // 计算缩放因子 (96 DPI 是标准)
            return dpi / 96.0;
        }
        XFree(data);
    }
    return 0;
}

// 从 KDE 设置获取缩放值
double get_scale_from_kde_settings(Display *dpy) {
    Atom kde_scale_atom = XInternAtom(dpy, "_KDE_SCREEN_SCALE_FACTORS", False);
    if (kde_scale_atom == None) return 0;
    
    Atom actual_type;
    int actual_format;
    unsigned long nitems, bytes_after;
    unsigned char *data = NULL;
    
    // 获取 KDE 缩放属性
    if (XGetWindowProperty(dpy, DefaultRootWindow(dpy), kde_scale_atom, 0, 1024,
                           False, XA_STRING, &actual_type, &actual_format,
                           &nitems, &bytes_after, &data) == Success) {
        if (data && actual_type == XA_STRING && actual_format == 8) {
            // 查找当前屏幕的缩放值
            char *screen_name = DisplayString(dpy);
            char *p = strstr((char *)data, screen_name);
            
            if (p) {
                // 找到格式: "Screen0=1.5"
                char *equals = strchr(p, '=');
                if (equals) {
                    double scale = atof(equals + 1);
                    XFree(data);
                    return scale;
                }
            }
        }
        XFree(data);
    }
    return 0;
}

// 获取缩放因子的主函数
double get_scale_factor(Display *dpy) {
    // 尝试获取 XSettings 缩放值
    double scale = get_scale_from_xsettings(dpy);
    if (scale > 0) return scale;
    
    // 尝试获取 GTK 缩放设置
    scale = get_scale_from_gtk_settings(dpy);
    if (scale > 0) return scale;
    
    // 尝试获取 KDE 缩放设置
    scale = get_scale_from_kde_settings(dpy);
    if (scale > 0) return scale;
    
    // 默认返回 1.0 (100%)
    return 1.0;
}


int main() {
    Display *dpy = XOpenDisplay(NULL);
    if (!dpy) {
        fprintf(stderr, "无法打开显示\n");
        return 1;
    }
    
    double scale = get_scale_factor(dpy);
    printf("屏幕缩放因子: %.2f\n", scale);
    
    XCloseDisplay(dpy);
    return 0;
}
